
#include "UtilManager.h"

using namespace ttg::extras::serialization;
using namespace ttg::utils;
using namespace ttg::services;

//-------------------
//--- UtilManager ---
//-------------------

const double UtilManager::UPDATE_RATE = 0.25;
UtilManager *UtilManager::ref = NULL;

UtilManager::UtilManager()
	:ttg::services::Service("UtilManager", "Timer DllLoader Logger")
{
	TimeEventID = 0;
	internal_sets = NULL;
	makeRegistration();
}

void UtilManager::onTick(double time)
{
	updateDevices(DeviceAnalyzer::getRef()->getDevices());
}

void UtilManager::init(UtilityProps &utility)
{
	//Checking.
	if (ttg_internal::utils::UtilManagerDll::getRef()->initUtility == NULL)
		switch (utility.onError)
		{
			case UtilityProps::ShowMessage:
				MessageBoxA(NULL,
							"Cannot load UtilManager. Some functionality will be unavaible.",
							"Error",
							MB_OK);
				break;

			case UtilityProps::ThrowError:
				throw Error(Error::FATAL, "UtilManagerLoader", "init",
							"Cannot load UtilManager");
				break;

			case UtilityProps::DoNothing:
			default:
				break;
		}
	else
	{
		//Serializing.
		ByteSerializer serializer(false);
		serializer.serializeObject(&utility, "props");
		//Initing.
		ttg_internal::utils::UtilManagerDll::getRef()
			->initUtility(serializer.getData(), serializer.getSize());
	}
}

void UtilManager::updateDevices(std::vector<ttg::services::DeviceInfo *> &devices)
{
	if (ttg_internal::utils::UtilManagerDll::getRef()->updateUtility_Devices != NULL)
	{
		//Serializing.
		ByteSerializer serializer(false);
		serializer.serializeInt((int)devices.size(), "count");
		for (size_t i = 0; i < devices.size(); i++)
			serializer.serializeObject(devices[i], "device");
		//Updating.
		ttg_internal::utils::UtilManagerDll::getRef()
			->updateUtility_Devices(serializer.getData(), serializer.getSize());
	}
}

void UtilManager::close(const char *name)
{
	if (ttg_internal::utils::UtilManagerDll::getRef()->closeUtility != NULL)
		ttg_internal::utils::UtilManagerDll::getRef()->closeUtility(name);
}

void UtilManager::startUnSafe(std::vector<ttg::services::Service *> &deps, const char *params)
{
	//Binding.
	if (!ttg_internal::utils::UtilManagerDll::getRef()->bind())
	{
		ttg::services::Logger::getRef()->addError(
			ttg::Error(ttg::Error::FATAL, "UtilManager", "startUnSafe",
					   "Cannot find \"UtilManager.dll\": some functionality will be unavailable"));
		return;
	}
	//Initing.
	ttg_internal::utils::UtilManagerDll::getRef()->init();
	//<fix_me>
	TimeEventID = ttg::services::Timer::getRef()->setNotifier(
						ttg::structures::make_delegate(this, &UtilManager::onTick),
						UPDATE_RATE,
						true,
						true);
	//</fix_me>
	ttg::services::Timer::getRef()->enableNotifier(TimeEventID);
	//Creating.
	internal_sets = new ttg_internal::utils::InternalSets();
}

void UtilManager::stopUnSafe()
{
	//Releasing.
	SAFE_DELETE(internal_sets);
	//Closing.
	ttg::services::Timer::getRef()->disableNotifier(TimeEventID);
	ttg_internal::utils::UtilManagerDll::getRef()->close();
	//Unbinding.
	ttg_internal::utils::UtilManagerDll::getRef()->unBind();
}

void UtilManager::activateWindow()
{
	if (ttg_internal::utils::UtilManagerDll::getRef()->activateWindow != NULL)
		ttg_internal::utils::UtilManagerDll::getRef()->activateWindow();
	else
		ttg::services::Logger::getRef()->addError(
			ttg::Error(ttg::Error::FATAL, "UtilManager", "activateWindow",
					   "UtilManager.dll was not loaded"));
}
